import Koa from "koa";
// import bodyParser from "koa-bodyparser";
import { onerror } from "koa-onerror";
import logger from "koa-logger";
import * as koaBody from "koa-body";
import { File } from "formidable";
import path from "path";
import fs from "fs";
import errorHandler from "./error-handle.ts";
import router from "../router/index.ts";
import operLogMiddleware from "@/middleware/operLog.middleware.ts";
import config from "./config.ts";
import serve from "koa-static";
import mount from "koa-mount";

// 创建 Koa 实例
const app = new Koa();
// 跨域
// app.use(core);

// 自动解析请求体数据，将 JSON、表单和文本类型的数据解析为对象赋值到 ctx.request.body。
// 创建上传目录（若不存在）
const UPLOAD_DIR = config.UPLOAD_DIR;
if (!fs.existsSync(UPLOAD_DIR)) {
  fs.mkdirSync(UPLOAD_DIR, { recursive: true });
}

// 配置 koa-body
app.use(
  koaBody.koaBody({
    // 基础配置
    multipart: true, // 启用 multipart 表单解析（文件上传必须）
    urlencoded: true, // 解析 application/x-www-form-urlencoded
    json: true, // 解析 application/json
    text: true, // 解析 text/plain
    patchNode: true, // 使用 Node.js 原生的 FormData 解析（默认 false）
    patchKoa: true, // 将解析结果挂载到 ctx.request.body（默认 false）

    // 文件上传配置（formidable 选项）
    formidable: {
      uploadDir: UPLOAD_DIR, // 文件上传目录
      keepExtensions: true, // 保留文件扩展名
      maxFields: 1000, // 最大表单字段数
      maxFieldsSize: 2 * 1024 * 1024, // 表单字段最大大小（2MB）
      maxFileSize: 10 * 1024 * 1024, // 单个文件最大大小（10MB）
      maxFiles: 10, // 最大上传文件数
      hashAlgorithm: "md5", // 计算文件哈希（可选：md5/sha1）
      multiples: true, // 允许多文件上传（单个字段多个文件）

      // 文件上传进度回调
      onFileBegin: (name: string, file: File) => {
        // 可在此修改文件保存路径或文件名
        const ext = path.extname(file.originalFilename || "");
        const base = path.basename(file.originalFilename || "");
        file.newFilename = `${base + "-" + Date.now()}${ext}`; // 自定义文件名
        file.filepath = path.join(UPLOAD_DIR, file.newFilename);
      },
    },
    // 错误处理
    onError: (err: any) => {
      console.error("文件上传错误:", err);
    },
    parsedMethods: ["POST", "PUT", "PATCH", "DELETE"] as any[], // 只解析这些 HTTP 方法
    includeUnparsed: false, // 是否包含原始未解析数据
    formLimit: "56kb", // 表单数据最大大小
    jsonLimit: "1mb", // JSON 数据最大大小
    textLimit: "56kb", // 文本数据最大大小
    encoding: "utf-8", // 字符编码
  })
);
app.use(
  mount(
    "/uploads",
    serve(UPLOAD_DIR, {
      maxage: 60 * 1000, // 浏览器缓存时间（毫秒）
      gzip: true, // 启用 Gzip 压缩
      defer: false, // 是否延迟处理（false 表示优先处理静态资源）
    })
  )
);
app.use(operLogMiddleware); // 再注册日志中间件
// 添加全局未捕获Promise处理
process.on("unhandledRejection", (reason, promise) => {
  console.error("未处理的Promise拒绝:", reason);
});
// error 处理  并不冲突 koa-error 用于用户响应，后者日志报警
// koa-error
onerror(app);
// 监听错误
app.on("error", errorHandler);

// logger koa-logger 是用于开发环境， 而自定义用于统一输出、归档或远程收集
// 自动打印每个 HTTP 请求的日志（方法、路径、响应时间等）。
app.use(logger());
// 自定义日志中间件，记录每个请求的响应时间。
// 注册路由（包括 Swagger 文档路由）
app.use(router.routes());
app.use(router.allowedMethods());

export default app;
